package com.druid.common.config.secutity;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.druid.entity.CeSecurityResource;
import com.druid.entity.CeSecurityRolePermission;
import com.druid.entity.CeUser;
import com.druid.service.managementservice.ICeSecurityResourceService;
import com.druid.service.managementservice.ICeSecurityRolePermissionService;
import com.druid.service.managementservice.ICeUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.AuthorizationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * springSecurity授权配置
 */
@Component("rbacPermission")
@RequiredArgsConstructor
public class RbacPermission {

    private final AntPathMatcher antPathMatcher = new AntPathMatcher();

    private final ICeUserService iCeUserService;

    private final ICeSecurityRolePermissionService iCeSecurityRolePermissionService;

    private final ICeSecurityResourceService iCeSecurityResourceService;

    public boolean hasPermission(HttpServletRequest request, Authentication authentication) throws AccessDeniedException {

        Object principal = authentication.getPrincipal();
        boolean hasPermission = false;
        if(principal instanceof UserDetails) {
            String username = ((UserDetails) principal).getUsername();
            // 获取用户角色id
            LambdaQueryWrapper<CeUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(CeUser::getUsername, username);
            CeUser ceUser = iCeUserService.getOne( lambdaQueryWrapper );
            //  获取用户权限列表
            LambdaQueryWrapper<CeSecurityRolePermission> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            lambdaQueryWrapper1.eq(CeSecurityRolePermission::getRoleId,ceUser.getRoleId());
            List<Integer> druidStuSecurityRolePermissionList = iCeSecurityRolePermissionService.list(lambdaQueryWrapper1).stream().map(CeSecurityRolePermission::getPermissionId).collect(Collectors.toList());
            if ( CollectionUtils.isEmpty( druidStuSecurityRolePermissionList ) ) throw new AuthorizationServiceException("该用户无权限");

            //  获取该用户权限下可访问的url资源列表
            LambdaQueryWrapper<CeSecurityResource> resourceLambdaQueryWrapper = new LambdaQueryWrapper<>();
            resourceLambdaQueryWrapper.in(CeSecurityResource::getPermissionId,druidStuSecurityRolePermissionList);
             List<CeSecurityResource> listUrl =  iCeSecurityResourceService.list( resourceLambdaQueryWrapper );

             // 校验该用户是否具有访问自愿的权限
            Set<String> urls = listUrl.stream().map(CeSecurityResource::getUrl).collect(Collectors.toSet());
            for (String url : urls) {
                if(antPathMatcher.match(url, request.getRequestURI())) {
                    hasPermission = true;
                    break;
                }
            }

        }
        if ( !hasPermission ) throw new AuthorizationServiceException("该用户无权限");

        return true;

    }
}
